/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bf;

import bf.operation.Operation;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import docmanager.business.objects.Usuario;

import bf.operation.*;
import java.util.*;
/**
 *
 * @author Juan Lucas
 */
abstract public class Controller extends HttpServlet
{

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {   
    	Logger.path = this.getLogPath();
    	response.setContentType("text/html;charset=UTF-8");
        // Levantamos la operacion.
        String operacion = (String) request.getParameter("op");
        
        HttpSession session = request.getSession();
        // Levantamos un security handler.
        SecurityHandler sh = this.getSecurityHandler();

        // Caso especial si la operacion es un login.
        String url = null;
 System.out.println("CONTROLLER: previo a validar el login");
 System.out.println("La operacion es " + operacion);

 
 		// Ojo que si el form es multi-part, requiere un trato especial!!
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        List multiPartItems = null;
        if (isMultipart)
        {
System.out.println("Es Multipart");
        	// Obtenemos el op.
        	FileItemFactory factory = new DiskFileItemFactory();
        	ServletFileUpload upload = new ServletFileUpload(factory);
			try {
				multiPartItems = upload.parseRequest(request);
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new ServletException();
			}
System.out.println("Tenemos " + multiPartItems.size() + " items.");
        	Iterator it = multiPartItems.iterator();
        	while (it.hasNext())
        	{
        		FileItem item = (FileItem) it.next();
System.out.println("Procesando item " + item.getFieldName());
        		if (item.isFormField())
        		{
        			if ("op".equals(item.getFieldName()))
        			{
        				operacion = item.getString();
        			}
        		}
        	}
        }
// Atencion!! Se agota la lista de items despues de hacer un parse.
// Se le debera pasar toda la informacion adicional.
/*
        if (isMultipart)
        {
System.out.println("Es Multipart Intento II");
        	// Obtenemos el op.
        	FileItemFactory factory = new DiskFileItemFactory();
        	ServletFileUpload upload = new ServletFileUpload(factory);
        	List items;
			try {
				items = upload.parseRequest(request);
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new ServletException();
			}
			System.out.println("Tenemos " + items.size() + " items.");			
        }
 */
        
 Logger.getInstance().log(Logger.NORMAL, "Ejecutando un login");
        if (operacion.equals("login"))
        {
            String login = (String) request.getParameter("login");
            String clave = (String) request.getParameter("clave");
            int res = sh.validarLogin(login, clave);
            if (res == SecurityHandler.CORRECTO)
            {
                session.setAttribute("usuario", login);
                request.setAttribute("mensaje", "Login exitoso");
                this.cargarUsuario(login, session);
                url = this.getMainURL();                
            }
            else
            {
                request.setAttribute("mensaje", "USUARIO O CLAVE INCORRECTOS");
            	url = this.getNoPermissionURL();
            }
        }
        else
        {
            String user = (String) session.getAttribute("usuario");
            Logger.getInstance().log(Logger.NORMAL, "El usuario " + user + " trata de ejecutar la operacion " + operacion);
            if (user == null)
            {
                url = this.getDefaultURL();
            }
            else if (sh.validate(operacion, user) != SecurityHandler.CORRECTO)
            {
            	request.setAttribute("mensaje", "Operacion Invalida");
            	Logger.getInstance().log(Logger.SEVERO, "El usuario " + user + " ha tratado de ejecutar la operacion " + operacion + " sin permiso de ejecucion.");
                url = this.getNoPermissionURL();
            }
            else
            {
                // AquI lo maneja el operationDispatcher.
                OperationDispatcher od = this.getOperationDispatcher();
                Operation op = od.obtenerOperacion(operacion);
                op.setObjetosMultipart(multiPartItems);
                try
                {
                	op.setResponse(response);
                    Map parametros = op.execute(request);
                    Iterator it = parametros.keySet().iterator();
                    while (it.hasNext())
                    {
                        String key = (String) it.next();
                        Object valor = parametros.get(key);
                        request.setAttribute(key, valor);
                    }
                    
                    url = op.getReturnURL();
                } catch (OperationException operationException)
                {
                    throw new ServletException(operationException);
                }
                
            }
        }
        System.out.println("CONTROLLER: redireccionamos a " + url);
        System.out.println("CONTROLLER: request vale " + request);
        System.out.println("CONTROLLER: response vale " + response);
        if (url != null)
        	request.getRequestDispatcher(url).forward(request, response);
        //response.sendRedirect(url);
   }

    protected abstract SecurityHandler getSecurityHandler();

    protected abstract OperationDispatcher getOperationDispatcher();

    protected abstract String getDefaultURL();
    
    protected abstract void cargarUsuario(String login, HttpSession session) throws ServletException;
    
    protected abstract String getNoPermissionURL();
    
    // Puede cambiar segun el usuario.
    protected abstract String getMainURL();
    
    protected abstract String getLogPath();
    
    
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo()
    {
        return "Short description";
    }// </editor-fold>
}
